package org.example.sec06;

import com.google.common.util.concurrent.Uninterruptibles;
import com.google.protobuf.Empty;
import com.seaway.models.sec06.*;
import io.grpc.stub.StreamObserver;
import org.example.sec08.respository.AccountRespository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

public class BankService extends BankServiceGrpc.BankServiceImplBase {
    private static final Logger LOG = LoggerFactory.getLogger(BankService.class);

    @Override
    public void getAccountBalance(BalanceCheckRequest request, StreamObserver<AccountBalance> responseObserver) {
        var ab = request.getAccountNumber();
        var balance = AccountRespository.getBalance(ab);
        AccountBalance build = AccountBalance.newBuilder()
                .setAccountNumber(balance)
                .setBalance(balance * 10)
                .build();
        LOG.info("当前线程:{}========>>> on next :{}",Thread.currentThread().getName(),balance);

        responseObserver.onNext(build);
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        responseObserver.onCompleted();

    }

    @Override
    public void getAllAccounts(Empty request, StreamObserver<AllAccountBalances> responseObserver) {
        var accountBalanceStream = AccountRespository.getAllAccounts()
                .entrySet()
                .stream()
                .map(e -> AccountBalance.newBuilder().setAccountNumber(e.getKey())
                        .setBalance(e.getValue()).build()).toList();
        var resp = AllAccountBalances.newBuilder()
                .addAllAccounts(accountBalanceStream).build();
        responseObserver.onNext(resp);
        responseObserver.onCompleted();
    }

    @Override
    public void withDraw(WithDrawRequest request, StreamObserver<Money> responseObserver) {
        int accountNumber = request.getAccountNumber();

        int amount = request.getAmount();
        Integer balance = AccountRespository.getBalance(accountNumber);
        if (amount > balance) {
            responseObserver.onCompleted();
            return;
        }
        for (int i = 0; i < 2; i++) {
            var m = Money.newBuilder().setAmount(10).build();
            responseObserver.onNext(m);
            AccountRespository.deductAccount(accountNumber,10);
        }
        Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS);
        responseObserver.onCompleted();
    }

    @Override
    public StreamObserver<DepositRequest> deposit(StreamObserver<AccountBalance> responseObserver) {
        return null;
    }

}
